/*
 * AutomatoProduto.h
 *
 *  Created on: 24/10/2012
 *      Author: vagner
 */

#ifndef AUTOMATOPRODUTO_H_
#define AUTOMATOPRODUTO_H_
#include "MyMatrix.h"
#include "Automato.h"

typedef struct{
	int idEstado;
	std::pair<int,int> estados;
}EstadoProduto;

typedef MyMatrix TabelaTransicao;
typedef std::vector<char> Alfabeto;


class AutomatoProduto {
private:
	Automato* M1;
	Automato* M2;
	int numEstados;
	std::vector<EstadoProduto> conjuntoEstados;
	TabelaTransicao* tabelaTransicao;
	Alfabeto sigma;
	const static int MODO_0 = 0;
	const static int MODO_1 = 1;

	//Constroi um produto de dois automatos sem estado inútil
	void constroiEstadoProduto();
	//Retorna a posicao de um simbolo no alfabeto
	int getIndexSimbolo(char& simbolo) const;
	//Insere uma transição na tabela de transição
	void insereTabelaTransicao(int& estadoOrigem, char simbolo, int& estadoDestino);
	//Verifica se um determinado estado está no automato;
	int isInAutomatoProduto(const EstadoProduto& estadoProduto) const;
	//Verifica se a linguagem reconhecidas por M1 e M2 são disjuntas;
	void analisaDisjuncao();
	/*
	 * Verifica se a linguagem reconhecida por M1 é subconjunto propria da
	 * linguagem reconhecida por M1 (modo 0) ou se a linguagem de M2 é subconjunto
	 * proprio de M1 modo(1);
	 */
	void analisaSubconjuntoProprio(int modo);
	/*
		 * Verifica se a linguagem reconhecida por M1 é subconjunto da
		 * linguagem reconhecida por M1 (modo 0) ou se a linguagem de M2 é subconjunto
		 * de M1 modo(1);
		 */
	void analisaSubconjunto(int modo);
	/*Verifica se a linguagem reconhecida por M1 e M2
	 * são iguais, returnando true para este caso
	 */
	void analisaIgualdade();

	//Gera uma palavra de uma forma não deterministica a partira de uma lista de estados
	void geraPalavra(std::string& palavraGerada, const std::vector<int>& estadosPercorridos);
	//Compara se dois conjuntos de estão são identicos
	bool comparaConjuntos(std::vector<int> idEstados,std::vector<EstadoProduto>& estadosProdutos);
	//Excluido acesso ao construtor padrao
	AutomatoProduto();

public:
	AutomatoProduto(Automato* M1,Automato* M2);
	void show()const;
	void analisaLinguagens();

	virtual ~AutomatoProduto();
};

#endif /* AUTOMATOPRODUTO_H_ */
